﻿using System;
using System.Diagnostics;
using System.Text;
using System.Security.Cryptography.X509Certificates;
using System.Net.Security;
using System.IO;
using System.Net;
using System.Net.Cache;
using System.IO.Compression;
using CommonTools.Storage;

namespace CommonTools.Net
{
    public class Http
    {

        #region 模拟表单提交

        /// <summary>
        /// 模拟表单提交
        /// </summary>
        /// <param name="url">地址</param>
        /// <param name="method">方式</param>
        /// <param name="parmeter">参数</param>
        /// <param name="referer">引用页面</param>
        /// <param name="html">返回Html源码</param>
        /// <param name="credentials"></param>
        /// <param name="cookieContainer">网页Cookie</param>
        /// <param name="encoding">网页编码方式</param>
        /// <param name="contentType"></param>
        /// <returns></returns>
        public static CookieContainer FormSubmit(
            string url,
            out string html,
            string method = "get",
            string parmeter = "",
            string referer = "",
            NetworkCredential credentials = null,
            CookieContainer cookieContainer = null,

            Encoding encoding = null,
            string contentType = "application/x-www-form-urlencoded"
            )
        {
            url = method.ToLower().Equals("get") ? parmeter == "" ? url : string.Format("{0}?{1}", url, parmeter) : url;
            var req = WebRequest.Create(url) as HttpWebRequest;
            cookieContainer = cookieContainer ?? new CookieContainer();
            encoding = encoding ?? Encoding.Default;

            if (req != null)
            {
                req.CookieContainer = cookieContainer;
                req.Credentials = credentials ?? req.Credentials;
                req.AllowAutoRedirect = true;
                req.Method = method;
                req.Referer = referer;
            }

            Stream stream;
            if (method.ToLower().Equals("post"))
            {
                req.ContentType = contentType;
                req.ContentLength = encoding.GetByteCount(parmeter);
                byte[] data = encoding.GetBytes(parmeter);
                stream = req.GetRequestStream();
                stream.Write(data, 0, data.Length);
                stream.Close();
            }
            //发送请求并获取相应回应数据
            var rep = req.GetResponse() as HttpWebResponse;
            //直到request.GetResponse()程序才开始向目标网页发送Post请求

            stream = rep.GetResponseStream();

            var streamReader = new StreamReader(stream, encoding);
            //结果网页（html）代码
            html = streamReader.ReadToEnd();

            //返回网页Cookie
            return req.CookieContainer;
        }
        #endregion

        #region 转换Cookie
        public static CookieContainer StringToCookie(string cookieTxt, string domain)
        {
            var myCookieContainer = new CookieContainer();

            string cookieStr = cookieTxt;
            string[] cookstr = cookieStr.Split(';');
            foreach (string str in cookstr)
            {
                string[] cookieNameValue = str.Split('=');
                var ck = new Cookie(cookieNameValue[0].Trim(), cookieNameValue[1].Trim()) { Domain = domain };
                myCookieContainer.Add(ck);
            }
            return myCookieContainer;
        }
        #endregion

        /// <summary>
        /// 读取网页
        /// </summary>
        /// <param name="url"></param>
        /// <param name="e"></param>
        /// <param name="credentials"></param>
        /// <param name="cookie"></param>
        /// <param name="errorLog"></param>
        /// <returns></returns>
        public static string ReadPage(string url, Encoding e = null, NetworkCredential credentials = null, bool errorLog = false)
        {

            try
            {
                var uri = new Uri(url);
                var req = (HttpWebRequest)WebRequest.Create(uri);
                req.Credentials = credentials ?? req.Credentials;
                var res = (HttpWebResponse)req.GetResponse();
                var reader = new StreamReader(res.GetResponseStream(), e ?? Encoding.Default);
                string result = reader.ReadToEnd();
                reader.Close();
                return result;
            }
            catch (Exception ex)
            {
                if (errorLog) Logs.SaveObject(ex);
                return "";
            }
        }

        /// <summary>
        /// 读取网页返回读取时间
        /// </summary>
        /// <param name="url"></param>
        /// <param name="time"></param>
        /// <param name="e"></param>
        /// <param name="errorLog"></param>
        /// <returns></returns>
        public static string ReadPage(string url, out int time, Encoding e = null, bool errorLog = false)
        {
            var stw = new Stopwatch();
            stw.Start();
            try
            {
                var uri = new Uri(url);
                var req = (HttpWebRequest)WebRequest.Create(uri);
                var res = (HttpWebResponse)req.GetResponse();
                var reader = new StreamReader(res.GetResponseStream(), e ?? Encoding.Default);
                string result = reader.ReadToEnd();
                reader.Close();
                stw.Stop();
                time = stw.Elapsed.Seconds;
                return result;
            }
            catch (Exception ex)
            {
                if (errorLog) Logs.SaveObject(ex);
                time = -1;
                return "";
            }
        }

        /// <summary>    
        /// 从磁盘加载Cookie    
        /// </summary>    
        public static CookieContainer LoadCookiesFromDisk()
        {
            CookieContainer cc;
            string cookieFile = Environment.GetFolderPath(Environment.SpecialFolder.Cookies) + "\\webclient.cookie";
            if (!File.Exists(cookieFile)) return null;

            FileStream fs = null;
            try
            {
                fs = new FileStream(cookieFile, FileMode.Open, FileAccess.Read, FileShare.Read);
                var formater = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                cc = (CookieContainer)formater.Deserialize(fs);
            }
            finally
            {
                if (fs != null) fs.Close();
            }
            return cc;
        }
    }
}
